#ifndef UVBOTLIB_H
#define UVBOTLIB_H

#include <cmath>
#include <string>
#include <vector>
#include <iostream>
//#include <winsock.h>
#include <stdio.h>

#include "connectionWin.h"

using namespace std;


//================== tokenizer.h ======================
#define TOKENIZER_H

#define DEFAULT_DELIMS " \t\n\r"
#define QUOTE '"'
#define QUOTE_STR "\""

class Tokenizer {
 public:
  Tokenizer(string t);
  Tokenizer(string t, string d);
  string getText() { return text; }
  string operator[](int index);
  int size() { return (int) tokens.size(); }

 private:
  string text;
  string delims;
  vector<string> tokens;
  int useQuotes;    // IF TRUE, USE QUOTES IN PARSING

  void parse();
};

//============= connectionWin.h REMOVED ===============

//================== botutil.h ======================
#define BOTUTIL_H

class Loc
{
public:
	int x, y;
	Loc() { x = y = 0; }
	Loc(int nx, int ny) { x = nx; y = ny; }
};

string trim(string str);
string lookup(string str, string key);

//================== scan.h ======================
#define SCAN_H

class Scan
{
public:
    static const int INVALID = -1;
    static const char BOT_SCAN = 'b', PUP_SCAN = 'p';
    static const int P_POINTS = 0, P_RECHARGE = 1, P_REPAIR = 2,
      P_WEAPONS = 3, P_ARMOR = 4, P_SPEED = 5, P_SCAN = 6;
    Scan();
    Scan(string scanStr);
    int getId() { return id; }
    Loc getLoc() { return loc; }
    int getFacing() { return facing; }
    int getType() { return type; }
    int getPupType() { return pupType; }
    int getPupAmount() { return pupAmount; }
private:
    char type;
    int id;
    Loc loc;
    int facing;
    int pupType;
    int pupAmount;
};


//================== botstatus.h ======================
#define BOTSTATUS_H

#define PI 3.141592654

class BotStatus
{
public:
	int test;
    static const int DEF_FIRE_RANGE = 3, DEF_SCAN_RANGE = 5;
    static const int INVALID = -1;

    BotStatus();
    ~BotStatus();

    void parse(string statusStrIn);
    void deleteScans();

    string getCmdResult() { return cmdResult; }
    Loc getLoc() { return loc; }
    int getFacing() { return facing; }
    int getDamage() { return damage; }
    int getMaxDamage() { return maxDamage; }
    int getPower() { return power; }
    int getMaxPower() { return maxPower; }
    string getMap() { return map; }
    vector<Scan*> getScanTargets() { return scanTargets; }
    Scan getScan(int i);
    int getScanCount() { return (int)scanTargets.size(); }
    Scan getPupScan(int i);
    int getPupScanCount() { return (int)scanPups.size(); }
    int getFireRange() { return DEF_FIRE_RANGE; }
    int getScanRange() { return DEF_SCAN_RANGE; }
    int getTargetAngle(Scan s);
    float getTargetRange(Scan s);
    string getStatusStr() { return statusStr; }

    static int getAngle(Loc start, Loc end);
    static float getDistance(Loc l1, Loc l2);

private:
    // ASSIGNMENT OP AND COPY CONSTRUCTOR ARE PRIVATE TO
    // PREVENT COPYING, SINCE scanTargets WILL NOT BE
    // HANDLED CORRECTLY BY MEMBER WISE COPY.
    // BotStatus OBJECTS SHOULD BE PASSED BY REFERENCE.
    BotStatus& operator=(BotStatus&);
    BotStatus(BotStatus&);
    int facing, damage, maxDamage, power, maxPower;
    Loc loc;
    string cmdResult;
    string map;
    vector<Scan*> scanTargets;
    vector<Scan*> scanPups;
    string statusStr;    // ORIGINAL STATUS STRING
};

//================== uvbot.h ======================
#define UVBOT_H

class UvBot
{
public:
    static const int DFLT_STR_LEN = 128;

    UvBot();
    ~UvBot();
    string doCmd(string cmdStr);
    string connect();
    string connect(string hostName, int port);
    string connect(string hostName, int port, string botName);
    int getId() { return id; }
private:
    ConnectionWin conn;
    int id;
};

#endif
